quiche: support inplace filter chain update#17988
quiche: support inplace filter chain update#17988alyssawilk merged 15 commits intoenvoyproxy:mainfrom
Conversation
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
|
/assign @lambdai @mattklein123 |
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
|
api_compat failure is not related. This PR is ready for review! |
|
Ping? |
ggreenway
left a comment
There was a problem hiding this comment.
This looks really good overall. Thanks!
I'd like to have @mattklein123 take a look also; he's the expert in listener updates.
/wait
Signed-off-by: Dan Zhang <danzh@google.com>
|
CI is failing; looks like a real failure: |
fixed |
|
/assign @mattklein123 |
mattklein123
left a comment
There was a problem hiding this comment.
I didn't review the H3 code, just the core code. Generally LGTM with a few questions/comments, thank you.
/wait
| if (!Runtime::runtimeFeatureEnabled( | ||
| "envoy.reloadable_features.udp_listener_updates_filter_chain_in_place") && |
There was a problem hiding this comment.
nit: snap this runtime value above.
source/server/listener_impl.cc
Outdated
| Network::Socket::Type::Stream || | ||
| Network::Utility::protobufAddressSocketType(config.address()) != | ||
| Network::Socket::Type::Stream) { | ||
| ; |
| // buildUdpListenerFactory() must come before buildListenSocketOptions() because the UDP | ||
| // listener factory can provide additional options. | ||
| buildUdpListenerFactory(socket_type, concurrency); |
There was a problem hiding this comment.
Just so I understand this is removed because this is the in-place update path, which was never supported before for UDP, and now that it is, we use the existing factory or just don't need a factory? Is that right?
There was a problem hiding this comment.
Yes, we already setup udp_listener_config_ in the original listener and it is shared with the new listener a few lines above.
|
/retest |
|
Retrying Azure Pipelines: |
mattklein123
left a comment
There was a problem hiding this comment.
Thanks LGTM with small remaining comments.
/wait
| * route config: added :ref:`dynamic_metadata <envoy_v3_api_field_config.route.v3.RouteMatch.dynamic_metadata>` for routing based on dynamic metadata. | ||
| * sxg_filter: added filter to transform response to SXG package to :ref:`contrib images <install_contrib>`. This can be enabled by setting :ref:`SXG <envoy_v3_api_msg_extensions.filters.http.sxg.v3alpha.SXG>` configuration. | ||
| * thrift_proxy: added support for :ref:`mirroring requests <envoy_v3_api_field_extensions.filters.network.thrift_proxy.v3.RouteAction.request_mirror_policies>`. | ||
| * udp: allows updating filter chain in-place through LDS, which is supported by Quic listener. This will be No-op with error log in other UDP listener implementations. It can be reverted by ``envoy.reloadable_features.udp_listener_updates_filter_chain_in_place``. |
There was a problem hiding this comment.
I think this needs to be updated now that we will reject for non-QUIC?
| void updateListenerConfig(Network::ListenerConfig&) override { NOT_REACHED_GCOVR_EXCL_LINE; } | ||
| void onFilterChainDraining(const std::list<const Network::FilterChain*>&) override { | ||
| NOT_REACHED_GCOVR_EXCL_LINE; | ||
| } |
There was a problem hiding this comment.
Can you add some small comments on why this is not reached?
|
|
||
| void ConnectionHandlerImpl::addListener(absl::optional<uint64_t> overridden_listener, | ||
| Network::ListenerConfig& config) { | ||
| bool support_udp_in_place_filter_chain_update = Runtime::runtimeFeatureEnabled( |
| Network::Socket::Type::Stream || | ||
| Network::Utility::protobufAddressSocketType(config.address()) != | ||
| Network::Socket::Type::Stream) { | ||
| if (!Runtime::runtimeFeatureEnabled( |
There was a problem hiding this comment.
Does the code that you added in validateFilterChains need to be replicated here? I forget the control flow. Can you add a comment on why this is OK given the other check?
There was a problem hiding this comment.
No. The problematic config will be rejected later. The following newListenerWithFilterChain() will construct ListenerImpl object and throw if validateFilterChains() fails. validateFilterChains() in called in both ListenerImpl constructors so such config will be rejected no matter it's an in-place update or it's the start up.
Signed-off-by: Dan Zhang <danzh@google.com>
danzh2010
left a comment
There was a problem hiding this comment.
Added feature protection around filter chain validation
| * route config: added :ref:`dynamic_metadata <envoy_v3_api_field_config.route.v3.RouteMatch.dynamic_metadata>` for routing based on dynamic metadata. | ||
| * sxg_filter: added filter to transform response to SXG package to :ref:`contrib images <install_contrib>`. This can be enabled by setting :ref:`SXG <envoy_v3_api_msg_extensions.filters.http.sxg.v3alpha.SXG>` configuration. | ||
| * thrift_proxy: added support for :ref:`mirroring requests <envoy_v3_api_field_extensions.filters.network.thrift_proxy.v3.RouteAction.request_mirror_policies>`. | ||
| * udp: allows updating filter chain in-place through LDS, which is supported by Quic listener. This will be No-op with error log in other UDP listener implementations. It can be reverted by ``envoy.reloadable_features.udp_listener_updates_filter_chain_in_place``. |
| void updateListenerConfig(Network::ListenerConfig&) override { NOT_REACHED_GCOVR_EXCL_LINE; } | ||
| void onFilterChainDraining(const std::list<const Network::FilterChain*>&) override { | ||
| NOT_REACHED_GCOVR_EXCL_LINE; | ||
| } |
|
|
||
| void ConnectionHandlerImpl::addListener(absl::optional<uint64_t> overridden_listener, | ||
| Network::ListenerConfig& config) { | ||
| bool support_udp_in_place_filter_chain_update = Runtime::runtimeFeatureEnabled( |
| Network::Socket::Type::Stream || | ||
| Network::Utility::protobufAddressSocketType(config.address()) != | ||
| Network::Socket::Type::Stream) { | ||
| if (!Runtime::runtimeFeatureEnabled( |
There was a problem hiding this comment.
No. The problematic config will be rejected later. The following newListenerWithFilterChain() will construct ListenerImpl object and throw if validateFilterChains() fails. validateFilterChains() in called in both ListenerImpl constructors so such config will be rejected no matter it's an in-place update or it's the start up.
|
/assign @alyssawilk for HTTP/3 side code. |
|
🙀 Error while processing event: |
|
/assign @alyssawilk |
|
@ggreenway mind taking another look? |
alyssawilk
left a comment
There was a problem hiding this comment.
Thanks for tackling this one! Couple of nits below
source/server/active_tcp_listener.h
Outdated
|
|
||
| /** | ||
| * Update the listener config. The follow up connections will see the new config. The existing | ||
| * The follow up connections will see the new config. The existing |
There was a problem hiding this comment.
was this comment changed intentionally? I think it made more sense before
There was a problem hiding this comment.
It's by mistake. Fixed
| ASSERT_TRUE(response->waitForReset()); | ||
| } | ||
|
|
||
| class QuicInplaceLdsIntegrationTest : public QuicHttpIntegrationTest { |
There was a problem hiding this comment.
Can we not reuse LdsInplaceUpdateHttpIntegrationTest.ReloadConfigAddingFilterChain and friends?
There was a problem hiding this comment.
Unfortunately, that test uses various ALPN to distinguish filter chains, but QUIC only supports "h3".
There was a problem hiding this comment.
Gotcha. If you make any further changes can you comment as such? Or alternately if when you address the ALPN TODO you could then share code maybe TODO the test migration?
source/server/listener_impl.cc
Outdated
| open_connections_ = origin.open_connections_; | ||
|
|
||
| if (socket_type == Network::Socket::Type::Stream) { | ||
| // Apply below tcp only initialization. |
There was a problem hiding this comment.
// Apply the options below only for TCP.
(though I'm surprised socket options doesn't apply to UDP?)
There was a problem hiding this comment.
done.
buildSocketOptions() is not called for UDP in the other ListenerImpl constructor either. It initializes connection balancer and sets TCP fast open which doesn't apply to UDP.
alyssawilk
left a comment
There was a problem hiding this comment.
quiche part looks good. I'd appreciate Greg or Matt signing off on the reload since they're more familiar with that.
| ASSERT_TRUE(response->waitForReset()); | ||
| } | ||
|
|
||
| class QuicInplaceLdsIntegrationTest : public QuicHttpIntegrationTest { |
There was a problem hiding this comment.
Gotcha. If you make any further changes can you comment as such? Or alternately if when you address the ALPN TODO you could then share code maybe TODO the test migration?
|
/retest |
|
Retrying Azure Pipelines: |
|
@ggreenway @mattklein123 any other comments? |
|
Ping @ggreenway @mattklein123 |
|
Apologies; I'm very busy this week. I may not be able to review until next Monday. |
mattklein123
left a comment
There was a problem hiding this comment.
I'm OK from my side, thank you.
|
That's 2 senior reviewers so I'm inclined to just merge if no one objects |
I did a pass earlier, and I think all my concerns have been addressed. I vote for merging it. |
Commit Message: updateListenerConfig() and onFilterChainDraining() to ActiveListener interface and implement them in ActiveQuicListener. Unblock listener update for UDP listener.
Risk Level: high, touches LDS.
Testing: new integration tests
Fixes #13115